package cn.zl.GB28181.session;

import cn.yunbamboos.exception.AppException;
import cn.zl.config.ZLConfig;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

@Component
public class SSRCFactory implements InitializingBean {

    /**
     * 播流最大并发个数
     */
    private static final Integer MAX_STREAM_COUNT = 10000;

    @Resource
    private ZLConfig config;

    private final BlockingQueue<String> ssrcList = new ArrayBlockingQueue<>(MAX_STREAM_COUNT);

    public void initMediaServerSSRC(Set<String> usedSet) {
        String sipDomain = config.getSIPDomain();
        String ssrcPrefix = sipDomain.length() >= 8 ? sipDomain.substring(3, 8) : sipDomain;
        List<String> ssrcList = new ArrayList<>();
        for (int i = 1; i < MAX_STREAM_COUNT; i++) {
            String ssrc = String.format("%s%04d", ssrcPrefix, i);
            if (null == usedSet || !usedSet.contains(ssrc)) {
                ssrcList.add(ssrc);
            }
        }
        if (!this.ssrcList.isEmpty()) {
            ssrcList.clear();
        }
        this.ssrcList.addAll(ssrcList);
    }


    /**
     * 获取视频预览的SSRC值,第一位固定为0
     *
     * @return ssrc
     */
    public String getPlaySsrc() {
        return "0" + getSN();
    }

    /**
     * 获取录像回放的SSRC值,第一位固定为1
     */
    public String getPlayBackSsrc() {
        return "1" + getSN();
    }

    /**
     * 释放ssrc，主要用完的ssrc一定要释放，否则会耗尽
     *
     * @param ssrc 需要重置的ssrc
     */
    public void releaseSsrc(String ssrc) {
        if (ssrc == null) {
            return;
        }
        String sn = ssrc.substring(1);
        this.ssrcList.add(sn);
    }

    /**
     * 获取后四位数SN,随机数
     */
    private String getSN() {
        String sn;
        if (this.ssrcList.isEmpty()) {
            throw AppException.c("ssrc已经用完");
        } else {
            sn = this.ssrcList.poll();
        }
        return sn;
    }

    /**
     * 重置一个流媒体服务的所有ssrc
     */
    public void reset() {
        this.initMediaServerSSRC(null);
    }

    /**
     * 是否已经存在了某个MediaServer的SSRC信息
     */
    public boolean hasMediaServerSSRC() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.initMediaServerSSRC(null);
    }
}

